package asynctask

import (
	"fmt"
	"github.com/pkg/errors"
	"scase.io/application-auto-scaling-service/pkg/common"
	"scase.io/application-auto-scaling-service/pkg/db"
	event "scase.io/application-auto-scaling-service/pkg/service/event"
	"scase.io/application-auto-scaling-service/pkg/taskmgmt"
	"scase.io/application-auto-scaling-service/pkg/utils/logger"
)

type PodScaleInTask struct {
	TaskId   string
	GroupId  string
	PodNames []string
	BaseTask
	event *event.EventService
}

func NewPodScaleInTask(taskId, groupId string, podNames []string) *PodScaleInTask {
	return &PodScaleInTask{
		TaskId:   taskId,
		GroupId:  groupId,
		PodNames: podNames,
	}
}

func (t *PodScaleInTask) GetKey() string {
	return t.GroupId
}

// GetType get task type
func (t *PodScaleInTask) GetType() string {
	return db.TaskTypeDeletePod
}

func (t *PodScaleInTask) Run(log *logger.FMLogger) error {
	group, err := db.GetScalingGroupById("", t.GroupId)
	if err != nil {
		return err
	}

	t.event, err = event.NewEventService(group.ProjectId, nil, log)
	if err != nil {
		log.Error("[pod_scale_in] new event service error:%+v", err)
		return err
	}
	// 1. 移出伸缩组，数据库取消关联，使用deleting标记已被移出的pod
	if err := db.PodInfoTable().RemoveInstance(t.PodNames); err != nil {
		log.Error("[pod_scale_in] disassociate instance error:%+v", err)
		go t.event.BuildAndRegisterEvent("[Scale-in] failed", group.Id, fmt.Sprintf("scale-in fleet [%s] failed with error:%+v", group.FleetId, err.Error()),
			fmt.Sprintf("fleet [%s] scale in %d instance failed", group.FleetId, len(t.PodNames)), common.EventTraceStateIncident)
		return err
	}

	if db.UpdateCurrentPodsNumber(t.GroupId, log); err != nil {
		log.Error("[pod_scale_in] update group [%s] current instance num error:%+v", group.Id, err)
	}

	for _, pod := range t.PodNames {
		err := db.InsertDeletePodAsyncTask(pod, t.GroupId, group.ProjectId)
		if err != nil {
			// 若该任务正在运行，不处理
			if errors.Is(err, common.ErrDeleteTaskAlreadyExists) {
				continue
			}
			log.Error("[pod_scale_in] insert delete vm async task error:%+v", err)
			return err
		}
		taskmgmt.GetTaskMgmt().AddTask(NewDelPodTask(pod, group.ProjectId, t.GroupId))
	}

	go t.event.BuildAndRegisterEvent(fmt.Sprintf("[Scale-in-%d-pod] success", len(t.PodNames)), group.Id, fmt.Sprintf("scale-in fleet[%s] success, pods:%s ", group.FleetId, t.PodNames),
		fmt.Sprintf("fleet [%s] scale in %d instance success", group.FleetId, len(t.PodNames)), common.EventTraceStateNormal)
	log.Info("[pod_scale_in] group [%s] scaling in success", t.GroupId)
	return db.TxRecordPodGroupScalingTaskComplete(t.GroupId, t.TaskId)
}
